﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YArchitech.Revit;
using YJKArchMethodLibrary.Utils;
using YJKPreviewerControl;
using YJKRGeometry.CalculationAnalysis;

namespace DoorAndWindow
{
	public static class ImpDoorWinTagInsert
	{
		public static void Do(UIDocument m_uiDoc, Element elem, ElementId tId)
		{
			double num = Common.MMToFeet(200.0);
			num = num / 100.0 * (double)m_uiDoc.ActiveView.Scale;
			Transaction transaction = new Transaction(m_uiDoc.Document, "TAG");
            if (elem.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Doors)
			{
				try
				{
					IList<Element> list = ElementFiltering.FindSpecialElements(m_uiDoc.Document, typeof(IndependentTag), BuiltInCategory.OST_DoorTags);
					FamilyInstance familyInstance = (FamilyInstance)elem;
					double num2 = ImpDoorWinTagInsert.MinAreaBoundingBoxPoint(m_uiDoc, familyInstance.Symbol);
					transaction.Start();
					foreach (Element element in list)
					{
						if (((IndependentTag)element).TaggedLocalElementId.IntegerValue == elem.Id.IntegerValue)
						{
							m_uiDoc.Document.DeleteElement(element);
							m_uiDoc.Document.Regenerate();
						}
					}
					XYZ point = ((LocationPoint)familyInstance.Location).Point;
					Wall wall = (Wall)familyInstance.Host;
					double width = wall.Width;
					XYZ xyz = point - familyInstance.FacingOrientation * (ImpDoorWinTagInsert.GetTagHeightOffset(-familyInstance.FacingOrientation, m_uiDoc.ActiveView, true) + num2 * 0.5);
					IndependentTag independentTag = m_uiDoc.Document.Create.NewTag(m_uiDoc.ActiveView, elem, false, 0, 0, xyz);
					independentTag.ChangeTypeId(tId);
					transaction.Commit();
					return;
				}
				catch (Exception)
				{
					transaction.RollBack();
					return;
				}
			}
            if (elem.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Windows)
			{
				try
				{
					transaction.Start();
					IList<Element> list2 = ElementFiltering.FindSpecialElements(m_uiDoc.Document, typeof(IndependentTag), BuiltInCategory.OST_WindowTags);
					foreach (Element element2 in list2)
					{
						if (((IndependentTag)element2).TaggedLocalElementId.IntegerValue == elem.Id.IntegerValue)
						{
							m_uiDoc.Document.DeleteElement(element2);
							m_uiDoc.Document.Regenerate();
						}
					}
					FamilyInstance familyInstance2 = (FamilyInstance)elem;
					XYZ point2 = ((LocationPoint)familyInstance2.Location).Point;
					Wall wall2 = (Wall)familyInstance2.Host;
					double width2 = wall2.Width;
					XYZ xyz2 = point2 + familyInstance2.FacingOrientation * (ImpDoorWinTagInsert.GetTagHeightOffset(familyInstance2.FacingOrientation, m_uiDoc.ActiveView, false) + num + width2);
					IndependentTag independentTag2 = m_uiDoc.Document.Create.NewTag(m_uiDoc.ActiveView, elem, false, 0, 0, xyz2);
					independentTag2.ChangeTypeId(tId);
					transaction.Commit();
				}
				catch (Exception)
				{
					transaction.RollBack();
				}
			}
		}

		private static double MinAreaBoundingBoxPoint(UIDocument m_uiDoc, FamilySymbol familySymbol)
		{
			double num = 0.0;
			double num2 = 0.0;
			double num3 = 0.0;
			List<XYZ> list = new List<XYZ>();
			Document document = m_uiDoc.Document.EditFamily(familySymbol.Family);
			UIApplication application = m_uiDoc.Application;
			Transaction transaction = new Transaction(document, "Type");
			try
			{
				transaction.Start();
				FamilyManager familyManager = document.FamilyManager;
				FamilyType currentType = familyManager.CurrentType;
				FamilyType familyType = null;
				foreach (object obj in familyManager.Types)
				{
					if (obj is FamilyType && (obj as FamilyType).Name.Equals(familySymbol.Name))
					{
						familyType = (obj as FamilyType);
						break;
					}
				}
				if (familyType != null)
				{
					familyManager.CurrentType = familyType;
				}
				Legend family2DImg = LegendCommon.GetFamily2DImg(application, document, LegendType.DoorWindows);
				familyManager.CurrentType = currentType;
				List<XYZ> list2 = new List<XYZ>();
				List<CurveInfo> curves = family2DImg.Curves;
				foreach (CurveInfo curveInfo in curves)
				{
					Curve curveObj = curveInfo.CurveObj;
					list2.Add(curveObj.GetEndPoint(0));
					list2.Add(curveObj.GetEndPoint(1));
				}
				list2 = list2.Distinct(new XYZCompare()).ToList<XYZ>();
				MinAreaBoundingBoxCalculator.MinAreaRect(list2, ref list, ref num2, ref num3);
				foreach (XYZ xyz in list)
				{
					if (num < xyz.Y)
					{
						num = xyz.Y;
					}
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
			return num;
		}

		private static double GetTagHeightOffset(XYZ facingOrientation, View view, bool isDoor)
		{
			double num = Common.MMToFeet(550.0);
			if (!isDoor)
			{
				num = Common.MMToFeet(350.0);
			}
			num = num / 100.0 * (double)view.Scale;
			double num2 = Geometry.getAngle(XYZ.Zero, facingOrientation);
			num2 = Geometry.formatAngle(num2 + Math.PI*.5);
			if (Geometry.GreaterThan(num2, Math.PI*.5) && Geometry.Lessthan_Or_Equal(num2, 4.71238898038469))
			{
				return -num;
			}
			return num;
		}

		private static XYZ Get2d(XYZ pt)
		{
			return new XYZ(pt.X, pt.Y, 0.0);
		}
	}
}
